package protocol.work.connection.data;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import protocol.common.entity.HttpConnConfig;
import protocol.common.util.MapUtil;
import protocol.work.connection.AbstractConnection;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import com.ibatis.sqlmap.client.SqlMapClient;

public class DataQueryConnection extends AbstractConnection{
	protected String queryPrefix;
	protected SqlMapClient sqlMapClient;
	protected HttpConnConfig httpConnConfig;
	
	public DataQueryConnection(SqlMapClient sqlMapClient,HttpConnConfig httpConnConfig){
		super(httpConnConfig.getChannle());
		this.sqlMapClient = sqlMapClient;
		this.httpConnConfig = httpConnConfig;
		this.queryPrefix = this.httpConnConfig.getSendCacheKey();
		super.setName("QueryData-"+this.httpConnConfig.getChannle());
	}
	
	public void run(){
		super.logger.info("<数据扫描> 线程开始,扫描通道"+this.httpConnConfig.getChannle()+"的数据");
		while(super.initMark){
			try{
				List<Map<String,String>> saveRedisMapList = new ArrayList<Map<String,String>>();
				String msgHeadStr = this.querySendSmsHead(saveRedisMapList);
				int saveRedisSize = this.querySendSmsMobile(saveRedisMapList, msgHeadStr);
				if(saveRedisSize>0){
					int resultSize = this.saveAndUpdateData(msgHeadStr, saveRedisMapList);
					super.logger.info("<数据扫描> 扫描待发数据，共计处理数据"+resultSize+"条");
				}else{
					super.threadSleep(5000L);
				}
			}catch (Exception e) {
				super.exceptionHandle(e);
			}
		}
		super.logger.info("<数据扫描> 线程终止,通道"+this.httpConnConfig.getChannle()+"的数据被释放");
	}
	
	@SuppressWarnings("unchecked")
	private String querySendSmsHead(List<Map<String,String>> saveRedisMapList) throws SQLException{
		StringBuilder msgHeadStr = new StringBuilder();
		List<Map<String,Object>> headInfoList = sqlMapClient.queryForList("DataPersistence.QuerySmsHead",httpConnConfig.getChannle());
		if(headInfoList!=null && headInfoList.size()>0){
			for(Map<String,Object> smsMap : headInfoList){
				Map<String,String> redisMap = this.parseMap(smsMap);
				redisMap.put("SaveType","map");
				saveRedisMapList.add(redisMap);
				msgHeadStr.append("'").append(smsMap.get("MSG_HEAD_ID")).append("',");
			}
			msgHeadStr.deleteCharAt(msgHeadStr.length());
		}
		return msgHeadStr.toString();
	}
	
	@SuppressWarnings("unchecked")
	private int querySendSmsMobile(List<Map<String,String>> saveRedisMapList,String msgHeadStr) throws SQLException{
		List<Map<String,Object>> mobileList = sqlMapClient.queryForList("DataPersistence.QuerySmsMobile",MapUtil.makeMap("MsgHeadStr,Channel",msgHeadStr,httpConnConfig.getChannle()));
		for(Map<String,Object> mobileMap : mobileList){
			Map<String,String> redisMap = this.parseMap(mobileMap);
			redisMap.put("SaveType","list");
			saveRedisMapList.add(redisMap);
		}
		return saveRedisMapList.size();
	}
	
	private int saveAndUpdateData(String msgHeadStr,List<Map<String,String>> saveRedisMapList) throws SQLException{
		Jedis jedis = super.getJedis();
		try{
			sqlMapClient.startTransaction();
			Transaction transaction = jedis.multi();
			for(Map<String,String> redisMap : saveRedisMapList){
				String type = redisMap.remove("SaveType");
				String mapKey = redisMap.get("MSG_HEAD_ID");
				String mobileKey = mapKey + "-Mobile";
				if(type.equals("map")){
					transaction.hmset(mapKey,redisMap);
				}else{
					transaction.lpush(mobileKey,redisMap.get("MOBILE"));
				}
				transaction.lpush(queryPrefix,mapKey);
			}
			sqlMapClient.update("DataPersistence.UpdateSmsMobile",MapUtil.makeMap("MsgHeadStr,Channel",msgHeadStr,httpConnConfig.getChannle()));
			sqlMapClient.commitTransaction();
			return transaction.exec().size();
		}catch (Exception e) {
		}finally{
			sqlMapClient.endTransaction();
			super.returnJedis(jedis);
		}
		return 0;
	}
	
	private Map<String,String> parseMap(Map<String,Object> databaseMap){
		Map<String,String> redisMap = new HashMap<String,String>();
		for(String key : databaseMap.keySet()){
			Object obj = databaseMap.get(key);
			redisMap.put(key,obj!=null ?obj.toString():"");
		}
		return redisMap;
	}
	
}
